package com.heima.article.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.cloud.commons.lang.StringUtils;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.heima.article.mapper.ArticleContentMapper;
import com.heima.article.service.ArticleFreemarkerService;
import com.heima.article.service.ArticleService;
import com.heima.file.service.FileStorageService;
import com.heima.model.article.pojos.ApArticle;
import com.heima.model.common.constants.ArticleConstants;
import com.heima.model.search.dtos.SearchArticleVo;
import freemarker.template.Configuration;
import freemarker.template.Template;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageBuilder;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.StringWriter;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

@Service
@Slf4j
@Transactional
public class ArticleFreemarkerServiceImpl implements ArticleFreemarkerService {
    @Autowired
    private ArticleContentMapper apArticleContentMapper;
    @Autowired
    private Configuration configuration;
    @Autowired
    private FileStorageService fileStorageService;
    @Autowired
    private ArticleService apArticleService;
    @Autowired
    private RabbitTemplate rabbitTemplate;
    /**
     * 生成静态化页面
     * @param apArticle
     * @param content
     */
    @Async
    @Override
    public void buildArticleToMinio(ApArticle apArticle, String content) {
        if(StringUtils.isNotBlank(content)){
            //1.文章内容通过freemarker生成静态html页面
            Template template = null;
            //2 输出流
            StringWriter writer = new StringWriter();
            try {
                template = configuration.getTemplate("article.ftl");
                //2.1 创建模型
                Map<String,Object> contentDataModel=new HashMap();
                //content是固定的，因为article.ftl中有<#if content??>${content}</#if>
                //因为apArticleContent.getContent()获取的是字符串，所以需要转换成对象
                contentDataModel.put("content", JSONArray.parseArray(content));
                //2.2 合成方法
                template.process(contentDataModel,writer);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
            //3.把静态页面上传到minio
            //3.1 文件流
            InputStream inputStream = new ByteArrayInputStream(writer.toString().getBytes());
            String path = fileStorageService.uploadHtmlFile("",apArticle.getId()+".html",inputStream);
            //4.把静态页面的路径保存到数据库
            apArticleService.update(Wrappers
                    .<ApArticle>lambdaUpdate()
                    .eq(ApArticle::getId,apArticle.getId())
                    .set(ApArticle::getStaticUrl,path));

            // 4.查询文章完整实体类发送mq消息同步ES
            SearchArticleVo vo = BeanUtil.toBean(apArticle, SearchArticleVo.class);
            vo.setStaticUrl(path);
            vo.setContent(content);
            Message message = MessageBuilder.withBody(JSONUtil.toJsonStr(vo).getBytes(StandardCharsets.UTF_8))
                    .setContentType(MessageProperties.CONTENT_TYPE_TEXT_PLAIN)
                    .build();
            rabbitTemplate.convertAndSend(ArticleConstants.ARTICLE_ES_SYNC_TOPIC, ArticleConstants.ARTICLE_ES_SYNC_ROUTINGKEY, message);
            log.info("文章发布同步更新es，id={}", vo.getId());
        }

    }
}
